import Phaser from 'phaser'
import Director from './Director';
/**
 * 抽象玩家具备的输入输出
 * 1.精灵初始化
 * 2.对精灵控制
 */
export default class PlayerBase {
    public roleKey: string = "";
    public serverInfo: any = null!;
    public spine: SpineGameObject = null!;
    public playerGroup: Phaser.GameObjects.Group = null!;
    public stopCoordinateSync: boolean = false;
    protected director: Director = null!;
    protected scene: Phaser.Scene = null!;
    protected gameObject: Phaser.GameObjects.GameObject | any = null!;
    /** 当前动作名称 */
    protected actionName: string = 'holdon';
    /** 动作结束回调记录 */
    protected actionEndCallback: Function = null!;
    /** 技能等释放过程此值应该为true  */
    protected statePlaying: boolean = false;
    protected debug: boolean = true;
    /** 玩家状态信息UI */
    public statusUi: Phaser.GameObjects.Container = null!;
    private statusUi_hp: Phaser.GameObjects.Graphics = null!;
    private statusUi_mp: Phaser.GameObjects.Graphics = null!;
    private statusUi_grade: Phaser.GameObjects.Text = null!;
    /** 技能距离范围区域展示 */
    public killDistanceRangeUi: Phaser.GameObjects.Graphics = null!;
    /** 技能攻击范围区域展示 */
    private killAattackRangeUi: Phaser.GameObjects.Graphics = null!;
    /** 范围选择状态 */
    private stateRangeSelect: boolean = false;

    /** 移动速度 */
    public moveTimeX: number = 1;
    public moveTimeY: number = 6;
    public moveSpeedX: number = 1;
    public moveSpeedY: number = 1;
    public moveTimeHandleX: number = 0;
    public moveTimeHandleY: number = 0;
    /** 玩家朝向 */
    public directionX: string = 'right';
    public directionY: string = 'up';
    /** 死亡状态 */
    public stateDead: boolean = false;
    /** 石化状态 */
    public stateShihua: boolean = false;
    public shihuaTime: number = 0;
    public shihuaTimeHandle: number = 0;
    public stateMovX: boolean = false;
    public stateMovY: boolean = false;
    public stateBeHit: boolean = false;

    protected width: number = 0;
    protected height: number = 0;
    /** 血量值 */
    protected hpMax: number = 600;
    protected hp: number = 600;
    /** 法力值 */
    protected mpMax: number = 600;
    protected mp: number = 600;

    /** 技能1 */
    protected skillOne: any = {};
    /** 技能2 */
    protected skillTwo: any = {};

    /** 当前物理攻击力 */
    protected physicsHurt: number = 60;
    /** 当前魔法攻击力 */
    protected magicHurt: number = 100;

    /** 魔法防御力 */
    protected magicDefense: number = 10;
    // protected magicCoefficient: number = 0.1;
    /** 物理防御力 */
    protected physicalDefense: number = 10;
    // protected physicalCoefficient: number = 0.1;
    /** 等级 */
    protected grade: number = 1;

    public isMonster: boolean = false;

    constructor(director: Director, key: string, isMonster: boolean = false) {
        this.director = director;
        this.scene = director.scene;
        this.isMonster = isMonster;
        this.init(key);
    }

    send(action: string, data: any = null) {
        if (window.client.stateConnect == true) {
            window.client.sendAction('Moba2D', action, data);
        }
    }

    public syncNetwork(): void {

        if (this.stopCoordinateSync === false && this.stateBeHit == false) {
            this.spine.x = this.serverInfo.role.x;
            this.spine.y = this.serverInfo.role.y;
        }
        this.hp = this.serverInfo.role.hp;
        this.mp = this.serverInfo.role.mp;

        this.magicDefense = this.serverInfo.role.magicDefense;
        this.physicalDefense = this.serverInfo.role.physicalDefense;
        this.magicHurt = this.serverInfo.role.magicHurt;
        this.physicsHurt = this.serverInfo.role.physicsHurt;

        this.skillOne = this.serverInfo.role.skillOne;
        this.skillTwo = this.serverInfo.role.skillTwo;

        this.hpMax = this.serverInfo.role.hpmax;
        this.mpMax = this.serverInfo.role.mpmax;

        this.grade = this.serverInfo.role.grade;

        this.updateStatusUI();

        if (this.serverInfo.isDead == true) {
            this.setActionDead();
        }


        if (this.serverInfo.isMoveUp) {
            this.moveUp();
        }
        if (this.serverInfo.isMoveDown) {
            this.moveDown();
        }
        if (this.serverInfo.isMoveLeft) {
            this.moveLeft();
        }
        if (this.serverInfo.isMoveRight) {
            this.moveRight();
        }
        if (this.serverInfo.isMoveUp == false && this.serverInfo.isMoveDown == false &&
            this.serverInfo.isMoveLeft == false && this.serverInfo.isMoveRight == false) {
            this.stopMoveX();
            this.stopMoveY();
            this.setActionIdle();
        }

        if (this.serverInfo.isActionAttack) {
            this.setActionAttack();
        }
        if (this.serverInfo.isActionSkillOne) {
            this.setActionSkillOne();
        }
        if (this.serverInfo.isActionSkillTwo) {
            this.setActionSkillTwo();
        }

    }

    protected createPalyerStatusUI(): void {

        this.statusUi_hp = this.scene.add.graphics().fillStyle(0x993333, 1).fillRect(14, 1, 50, 13);
        this.statusUi_mp = this.scene.add.graphics().fillStyle(0x009966, 1).fillRect(14, 14, 85, 4)
        this.statusUi_grade = this.scene.add.text(-4, 3, this.grade + '', { fontSize: '14px' })

        this.statusUi = this.scene.add.container(100, 200, [
            this.scene.add.graphics().fillStyle(0xAAAAAA, 1).fillRect(0, 0, 100, 20),
            this.scene.add.graphics().fillStyle(0x333333, 1).fillRect(1, 1, 98, 18),
            /** 血条 */
            this.statusUi_hp,
            /** 能量条 */
            this.statusUi_mp,
            this.scene.add.circle(0, 10, 16, 0x333333),
            this.scene.add.circle(0, 10, 14, 0x555555),
            this.statusUi_grade,
        ]);

        // this.scene.add.circle(this.spine.x,this.spine.y,200,0xffffff);
        // this.spine.add(this.statusUi)
        // this.gameObject.add(this.statusUi);

        this.updateStatusUI();
        this.updateHp();
        // this.rangeSelect();
    }

    /** 显示施法范围 */
    protected rangeSelect(width: number = 500, height: number = 300, skillWidth: number = 100, skillHeight: number = 100): void {
        if (this.killDistanceRangeUi != null) {
            this.killDistanceRangeUi.destroy();
            this.killDistanceRangeUi = null!;
        }
        this.stateRangeSelect = true;
        this.killDistanceRangeUi = this.scene.add.graphics().fillStyle(0xAAAAAA, 0.5).fillEllipse(this.spine.x, this.spine.y, width, height);
        this.killAattackRangeUi = this.scene.add.graphics().fillStyle(0xAAAAAA, 0.8).fillEllipse(this.spine.x, this.spine.y, skillWidth, skillHeight);
    }

    protected updateHp(): void {
        // this.hp = value;
        this.statusUi_hp.clear();
        this.statusUi_hp.fillStyle(0x993333, 1).fillRect(14, 1, (this.hp / this.hpMax * 100) * 85 / 100, 13);
    }

    protected updateStatusUI(): void {
        // return;
        if (this.directionX == 'left') {
            this.statusUi.x = this.getX();
        } else {
            this.statusUi.x = this.getX() + 10;
        }

        this.statusUi.y = this.getY() - this.getHeight() / 2 - 10;
        this.statusUi.depth = this.spine.depth;
    }

    private init(key: string): boolean {

        // let player: PlayerBase = new PlayerBase();
        this.roleKey = key;
        this.spine = this.scene.add.spine(400, 500, key, 'holdon', true);
        // this.spine.drawDebug = true;

        /** 加入到物理引擎 */
        this.gameObject = this.scene.matter.add.gameObject(<any>this.spine, false);
        this.scene.matter.setCollisionCategory([this.gameObject], 0);

        // this.scene.matter.overlap(this.gameObject, undefined, (bodyA: any, bodyB: any) => {
        //     console.log('overlap', bodyA, bodyB);
        // })
        if (this.spine == null) {
            console.error('PlayerBase.init => spirite is null');
            return false;
        }

        if (this.isMonster == false) {
            this.spine.scaleX = 0.4;
            this.spine.scaleY = 0.4
            this.width = this.spine.width * 0.4;
            this.height = this.spine.height * 0.4;
        } else {
            this.width = this.spine.width;
            this.height = this.spine.height;
        }

        console.log(this.width, this.height)
        this.createPalyerStatusUI();

        this.spine.on(Phaser.Animations.Events.ANIMATION_COMPLETE, () => {
            if (this.statePlaying === true) {
                this.statePlaying = false;
                this.actionComplete(this.actionName);
                if (this.stateShihua === true) {
                    return;
                }
                this.setActionIdle();
            }
        });

        /** 动作事件, 可用于技能攻击判定 */
        this.spine.on('event', (trackEntry: any, event: any) => {
            if (this.serverInfo.robot == false && window.userInfo.id === this.serverInfo.id) {
                console.log(event.data.name);
                this.send('action', {
                    name: this.actionName,
                    frame: event.data.name
                });
            }

            if (this.statePlaying == true) {
                this.actionEvent(this.actionName, event.data.name);
                if (event.data.name == 'back') {
                    if (this.actionName == 'att') {
                        this.send('actionAttackComple');
                    }
                    if (this.actionName == 'skill') {
                        this.send('actionSkillOneComple');
                    }
                    if (this.actionName == 'ultimateskill') {
                        this.send('actionSkillTwoComple');
                    }
                }
            }
        });
        return true;
    }

    /** 动作帧触发的事件 */
    protected actionEvent(action: string, actionEventName: string): void { }
    /** 动作结束 */
    protected actionComplete(action: string): void { }


    getWidth(): number {
        return this.width;
    }
    getHeight(): number {
        return this.height;
    }
    getX(): number {
        return this.spine.x - this.width / 2;

    }
    getY(): number {
        return this.spine.y - this.height / 2;
    }

    /** 置为空闲动作 */
    setActionIdle(): void {
        if (this.stateDead == true) return;
        if (this.stateShihua == true) return;
        if (this.statePlaying == true) return;
        if (this.actionName == 'holdon') return;
        this.actionName = 'holdon';
        this.stateShihua = false;
        this.stopMoveX();
        this.stopMoveY();
        if (this.actionEndCallback) {
            this.actionEndCallback(this.actionName);
        }
        this.spine.setAnimation(0, 'holdon', true);
    }

    /** 置为行走动作 */
    setActionMove(): void {
        if (this.statePlaying == true) return;
        if (this.actionName == 'move') return;
        this.actionName = 'move';
        this.spine.setAnimation(0, 'move', true);
        // this.send('ActionMove');
        console.log('setActionMove');
    }

    setAttackAction(key: string, loop: boolean = false): void {
        if (this.statePlaying == true) return;
        if (this.actionName == key) return;
        this.statePlaying = true;
        this.actionName = key;
        this.spine.setAnimation(0, key, loop);
    }

    /** 被击中
     * @param attPalyer 攻击者
     * @param physicsHurt 物理伤害
     * @param magicHurt 魔法伤害
     * @param repelValue 击退值
     * @param shihuaTime 石化时间
     */
    beHit(physicsHurt: number, magicHurt: number, repelValue: number = 0, shihuaTime: number = 0): void {
        let hurt: number = 0
        if (physicsHurt > 0) {
            hurt += Math.round(physicsHurt - this.physicalDefense);
        }
        if (magicHurt > 0) {
            hurt += Math.round(magicHurt - this.magicDefense);
        }

        let injuredText = this.scene.add.text(this.spine.x, this.spine.y - this.height, `-${hurt}`, { color: 'red', fontSize: 14, fontFamily: '微软雅黑' }).setOrigin(0.5);
        injuredText.depth = this.spine.depth + 9999;
        this.scene.tweens.add({
            targets: injuredText,
            y: injuredText.y - 100, // 上移100像素
            alpha: 0, // 逐渐变得透明
            duration: 2000, // 动画持续时间
            ease: 'Power1', // 动画缓动效果
            onComplete: () => {
                injuredText.destroy(); // 动画完成后销毁文本
            }
        })

        this.stopMoveX();
        this.stopMoveY();
        /** 是否击退 */
        if (repelValue != 0 && this.serverInfo.robot == false) {
            let currentX = this.spine.x;
            let backPosition: number = currentX + repelValue;
            if (this.serverInfo.robot == false && window.userInfo.id == this.serverInfo.id) {
                // this.send('berepelled', { value: repelValue });
            }
            this.stateBeHit = true;

            this.setPositionX(backPosition, () => {
                if (this.serverInfo.robot == false && window.userInfo.id == this.serverInfo.id) {
                    this.send('syncPosition', { x: this.spine.x, y: this.spine.y })
                }
                setTimeout(() => {
                    this.stateBeHit = false;
                }, 100);
            });
        }

        /** 是否石化 */
        if (shihuaTime > 0) {
            this.setActionShihua(shihuaTime);

        } else {
            this.setActionBeHit();
        }

        // if (this.hp <= 0) {
        //     this.hp = 0;
        //     this.setActionDead();
        //     console.log('死亡!')
        // }
        this.updateHp();

    }

    crit() {
        let injuredText = this.scene.add.text(this.spine.x, this.spine.y - this.height, '暴击', { color: '#FFCC99', font: 'bold 32px Arial', fontSize: 18, fontFamily: '微软雅黑' }).setOrigin(0.5);
        injuredText.depth = this.spine.depth + 9999;
        this.scene.tweens.add({
            targets: injuredText,
            y: injuredText.y - 100, // 上移100像素
            alpha: 0, // 逐渐变得透明
            duration: 2000, // 动画持续时间
            ease: 'Power1', // 动画缓动效果
            onComplete: () => {
                injuredText.destroy(); // 动画完成后销毁文本
            }
        })
    }

    missed() {
        let injuredText = this.scene.add.text(this.spine.x, this.spine.y - this.height, 'Miss', { color: '#FFFF66', font: 'bold 32px Arial', fontSize: 18, fontFamily: '微软雅黑' }).setOrigin(0.5);
        injuredText.depth = this.spine.depth + 9999;
        this.scene.tweens.add({
            targets: injuredText,
            y: injuredText.y - 100, // 上移100像素
            alpha: 0, // 逐渐变得透明
            duration: 2000, // 动画持续时间
            ease: 'Power1', // 动画缓动效果
            onComplete: () => {
                injuredText.destroy(); // 动画完成后销毁文本
            }
        })
    }

    /** 被击中动画 */
    setActionBeHit(): void {
        if (this.stateShihua == true) return;
        this.setAttackAction('behit');
    }
    stopMove(): void {
        this.stopMoveX();
        this.stopMoveY();
    }
    /** 石化 */
    setActionShihua(time: number = 3): void {
        if (this.stateDead == true) return;
        if (this.stateShihua == true) {
            this.shihuaTime += time;
            return;
        }
        this.statePlaying = false;
        this.stopMove();
        this.stateShihua = true;
        this.setAttackAction('shihua');
        this.shihuaTime = time;
        this.shihuaTimeHandle = setInterval(() => {
            if (this.stateDead == true) {
                this.stateShihua = false;
                clearInterval(this.shihuaTimeHandle);
                this.shihuaTimeHandle = 0;
                return;
            }
            if (this.shihuaTime > 0) {
                this.shihuaTime--;
            }
            if (this.shihuaTime <= 0) {
                this.stateShihua = false;
                this.setActionIdle();
                clearInterval(this.shihuaTimeHandle);
                this.shihuaTimeHandle = 0;
            }
        }, 1000);
    }

    /** 死亡 */
    setActionDead(): void {
        if (this.stateDead == true) return;
        this.stateDead = true;
        this.stopMove();
        this.spine.setAnimation(0, 'death', false, true);
    }

    /** 攻击动作 */
    setActionAttack(): void {
        if (this.stateDead == true) return;
        if (this.stateShihua == true) return;
        this.stopMove();
        this.setAttackAction('att');
    }

    /** 置为技能动作 */
    setActionSkillOne(callback: Function = null!): void {
        if (this.stateDead == true) return;
        if (callback) callback();
        if (this.stateShihua == true) return;
        this.stopMove();
        this.setAttackAction('skill');
    }

    /** 置为技能动作 */
    setActionSkillTwo(callback: Function = null!): void {
        if (this.stateDead == true) return;
        if (callback) callback();
        if (this.stateShihua == true) return;
        this.stopMove();
        this.setAttackAction('ultimateskill');
    }

    /** 设置角色方向 */
    setDirectionX(direction: string): void {
        if (this.directionX == direction) return;
        this.directionX = direction;
        if (this.directionX == 'right') {
            if (this.isMonster == false) {
                this.spine.scaleX = 0.4;
            } else {
                this.spine.scaleX = 1;
            }
        } else {
            if (this.isMonster == false) {
                this.spine.scaleX = -0.4;
            } else {
                this.spine.scaleX = -1;
            }
        }
    }


    /** 开启X轴移动定时器 */
    startMoveX(): void {
        return;
        // /** 控制X方向的定时器 */
        // if (this.moveTimeHandleX != 0) return;
        // this.moveTimeHandleX = setInterval(() => {
        //     if (this.stateMovX === false) return;
        //     if (this.directionX == 'right') {
        //         this.spine.x += this.moveSpeedX;
        //     } else if (this.directionX == 'left') {
        //         this.spine.x -= this.moveSpeedX;
        //     }

        //     this.updateStatusUI();

        // }, this.moveTimeX);
    }

    /** 停止X轴移动定时器 */
    stopMoveX(): void {
        return;
        this.stateMovX = false;
        if (this.moveTimeHandleX) {
            clearInterval(this.moveTimeHandleX);
            this.moveTimeHandleX = 0;
        }
    }

    /** 开启Y轴移动定时器 */
    startMoveY(): void {
        return;
        /** 控制Y方向的定时器 */
        if (this.moveTimeHandleY != 0) return;
        this.moveTimeHandleY = setInterval(() => {
            if (this.stateMovY == false) return;
            if (this.directionY == 'up') {
                this.spine.y -= this.moveSpeedY;
            } else if (this.directionY == 'down') {
                this.spine.y += this.moveSpeedY;
            }
            this.updateStatusUI();
        }, this.moveTimeY);
    }

    /** 停止Y轴移动定时器 */
    stopMoveY(): void {
        return;
        this.stateMovY = false;
        if (this.moveTimeHandleY) {
            clearInterval(this.moveTimeHandleY);
            this.moveTimeHandleY = 0;
        }
    }

    /** 向前左移动 */
    moveLeft(): void {
        if (this.stateDead == true) return;
        if (this.stateShihua == true) return;
        if (this.statePlaying == true) return;
        this.setDirectionX('left');
        this.setActionMove();
        this.stateMovX = true;
        this.startMoveX();
    }

    moveRight(): void {
        if (this.stateDead == true) return;
        if (this.stateShihua == true) return;
        if (this.statePlaying == true) return;
        this.setDirectionX('right');
        this.setActionMove();
        this.stateMovX = true;
        this.startMoveX();
    }
    moveUp(): void {
        if (this.stateDead == true) return;
        if (this.stateShihua == true) return;
        if (this.statePlaying == true) return;
        this.directionY = 'up';
        this.setActionMove();
        this.stateMovY = true;
        this.startMoveY();
    }

    moveDown(): void {
        if (this.stateDead == true) return;
        if (this.stateShihua == true) return;
        if (this.statePlaying == true) return;
        this.directionY = 'down';
        this.setActionMove();
        this.stateMovY = true;
        this.startMoveY();
    }

    setPositionX(tagX: number, callback: Function = null!): void {
        // this.spine.x = x;
        this.stopCoordinateSync = true;
        if (this.serverInfo.robot == false && window.userInfo.id == this.serverInfo.id) {
            console.log('syncPosition', this.serverInfo.nickname)
            this.send('syncPosition', { x: tagX });
        }

        this.scene.tweens.add({
            targets: this.spine,
            x: tagX,
            ease: 'Power2',
            duration: 100,
            onComplete: () => {
                this.updateStatusUI();
                if (callback !== null) {
                    callback();
                }
                if (this.serverInfo.robot == false && window.userInfo.id == this.serverInfo.id) {
                    console.log('syncPosition', this.serverInfo.nickname)

                    this.send('syncPosition', { x: this.spine.x, y: this.spine.y });
                }
                this.stopCoordinateSync = false;
            }
        })
        this.updateStatusUI();
    }

    setPositionY(y: number): void {
        this.spine.y = y;
        this.updateStatusUI();
    }

    public isDead(): boolean {
        return this.stateDead;
    }

    public attackScope(attachedLeft: number, attachedTop: number, attachedRight: number, attachedBottom: number, noDebug: boolean = false): number[] {
        let sx = this.getX() - attachedLeft;
        let sy = this.getY() - attachedTop;
        let ex = sx + this.getWidth() + attachedRight;
        let ey = sy + this.getHeight() + attachedBottom;
        if (noDebug == false && this.debug == true) {
            var graphics = this.scene.add.graphics();
            graphics.fillStyle(0xFF0000, 1);
            graphics.fillRect(sx, sy, ex - sx, ey - sy);

            this.scene.time.addEvent({
                delay: 2000,
                callback: () => {
                    graphics.destroy();
                },
            });
        }
        if (noDebug == false && this.debug == true) {
            console.log('width', ex - sx, 'height', ey - sy)
        }
        return [sx, sy, ex, ey];
    }

    public scope(sx: number, sy: number, ex: number, ey: number): void {
        var graphics = this.scene.add.graphics();
        graphics.fillStyle(0xF1F1F1, 1);
        graphics.setAlpha(0.5);
        graphics.fillRect(sx, sy, ex - sx, ey - sy);
        this.scene.time.addEvent({
            delay: 2000,
            callback: () => {
                graphics.destroy();
            },
        });

    }

    public update(): void {
        this.updateHp();
        this.updateStatusUI();
    }

}
